package com.ctshk.rpc.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.IsDeletedCode;
import com.ctshk.common.enums.SystemError;
import com.ctshk.common.model.PageResponse;
import com.ctshk.common.model.TokenUser;
import com.ctshk.common.utils.EntityUtil;
import com.ctshk.rpc.system.dto.*;
import com.ctshk.rpc.system.entity.MainDataTourGroup;
import com.ctshk.rpc.system.entity.MainDataTourGroupArea;
import com.ctshk.rpc.system.entity.MainDataTourGroupCode;
import com.ctshk.rpc.system.enums.StopStatusCode;
import com.ctshk.rpc.system.mapper.MainDataTourGroupAreaMapper;
import com.ctshk.rpc.system.mapper.MainDataTourGroupCodeMapper;
import com.ctshk.rpc.system.mapper.MainDataTourGroupMapper;
import com.ctshk.rpc.system.req.*;
import com.ctshk.rpc.system.service.IMainDataTourGroupService;
import com.ctshk.rpc.tour.service.ISeriesTripAppService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * <p>
 * 旅游组别表 服务实现类
 * </p>
 *
 * @author 谢诗宏
 * @since 2021-01-30
 */
@DubboService
public class MainDataTourGroupServiceImpl extends ServiceImpl<MainDataTourGroupMapper, MainDataTourGroup> implements IMainDataTourGroupService {

    @Autowired
    private MainDataTourGroupMapper mainDataTourGroupMapper;
    @Autowired
    private MainDataTourGroupAreaMapper mainDataTourGroupAreaMapper;
    @Autowired
    private MainDataTourGroupCodeMapper mainDataTourGroupCodeMapper;
    @DubboReference
    private ISeriesTripAppService iSeriesTripAppService;

    /**
     * 新增旅游组别
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result add(MainDataTourGroupAddReq req, TokenUser tokenUser) {
        //判断是否已存在该目的地
        List<MainDataTourGroupArea> list = mainDataTourGroupAreaMapper.selectListByAreaList(req.getAreaList());
        if (CollectionUtils.isNotEmpty(list)) {
            return Result.failed(SystemError.MAINDATA_4018);
        }
        MainDataTourGroup mainDataTourGroup = EntityUtil.copy(req, MainDataTourGroup.class);
        LocalDateTime now = LocalDateTime.now();
        mainDataTourGroup.setGmtCreate(now);
        mainDataTourGroup.setGmtModified(now);
        mainDataTourGroup.setModifiedId(tokenUser.getId());
        mainDataTourGroup.setIsDeleted(IsDeletedCode.NO.getCode());
        long id = IdWorker.getId();
        mainDataTourGroup.setId(id);
        mainDataTourGroupMapper.insert(mainDataTourGroup);
        for (MainDataTourGroupAreaReq mainDataTourGroupAreaReq : req.getAreaList()) {
            MainDataTourGroupArea mainDataTourGroupArea = EntityUtil.copy(mainDataTourGroupAreaReq, MainDataTourGroupArea.class);
            mainDataTourGroupArea.setCodeId(id);
            mainDataTourGroupArea.setCreateId(tokenUser.getId());
            mainDataTourGroupArea.setModifiedId(tokenUser.getId());
            mainDataTourGroupArea.setGmtCreate(now);
            mainDataTourGroupArea.setGmtModified(now);
            mainDataTourGroupArea.setIsDeleted(IsDeletedCode.NO.getCode());
            mainDataTourGroupAreaMapper.insert(mainDataTourGroupArea);
        }
        // 更新缓存
        CompletableFuture.runAsync(() -> {
            iSeriesTripAppService.tripHomeCatalogDTO();
        });
        return Result.success(id);
    }

    /**
     * 编辑旅游组别
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result update(MainDataTourGroupUpdateReq req, TokenUser tokenUser) {
        LocalDateTime now = LocalDateTime.now();
        QueryWrapper<MainDataTourGroupArea> areaQueryWrapper = new QueryWrapper<>();
        areaQueryWrapper.lambda().eq(MainDataTourGroupArea::getCodeId, req.getId());
        mainDataTourGroupAreaMapper.delete(areaQueryWrapper);
        List<MainDataTourGroupArea> mainDataTourGroupAreaList = EntityUtil.copyList(req.getAreaList(), MainDataTourGroupArea.class);
        for (MainDataTourGroupArea mainDataTourGroupArea : mainDataTourGroupAreaList) {
            mainDataTourGroupArea.setCodeId(req.getId());
            mainDataTourGroupArea.setModifiedId(tokenUser.getId());
            mainDataTourGroupArea.setCreateId(tokenUser.getId());
            mainDataTourGroupArea.setGmtCreate(now);
            mainDataTourGroupArea.setGmtModified(now);
            mainDataTourGroupArea.setIsDeleted(IsDeletedCode.NO.getCode());
            mainDataTourGroupAreaMapper.insert(mainDataTourGroupArea);
        }
        MainDataTourGroup mainDataTourGroup = EntityUtil.copy(req, MainDataTourGroup.class);
        mainDataTourGroup.setModifiedId(tokenUser.getId());
        mainDataTourGroup.setModifiedName(tokenUser.getUsername());
        mainDataTourGroup.setGmtModified(now);
        baseMapper.updateById(mainDataTourGroup);
        // 更新缓存
        CompletableFuture.runAsync(() -> {
            iSeriesTripAppService.tripHomeCatalogDTO();
        });
        return Result.success(req.getId());
    }

    /**
     * 编辑旅游组别状态
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateStatus(MainDataTourGroupUpdateStatusReq req, TokenUser tokenUser) {
        LocalDateTime now = LocalDateTime.now();
        MainDataTourGroup selectOne = baseMapper.selectById(req.getId());
        MainDataTourGroup mainDataTourGroup = EntityUtil.copy(req, MainDataTourGroup.class);
        if (selectOne.getStatus() == 0) {
            mainDataTourGroup.setStatus(1);
        } else {
            mainDataTourGroup.setStatus(0);
        }
        mainDataTourGroup.setModifiedId(tokenUser.getId());
        mainDataTourGroup.setGmtModified(now);
        mainDataTourGroup.setModifiedName(tokenUser.getUsername());
        mainDataTourGroupMapper.updateById(mainDataTourGroup);
        return Result.success(req.getId());
    }

    /**
     * 查询旅游组别
     */
    @Override
    public MainDataTourGroupQueryDTO query(MainDataTourGroupUpdateStatusReq req) {
        QueryWrapper<MainDataTourGroup> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MainDataTourGroup::getId, req.getId());
        MainDataTourGroup mainDataTourGroup = mainDataTourGroupMapper.selectOne(queryWrapper);
        MainDataTourGroupQueryDTO mainDataTourGroupQueryDTO = EntityUtil.copy(mainDataTourGroup, MainDataTourGroupQueryDTO.class);
        QueryWrapper<MainDataTourGroupArea> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(MainDataTourGroupArea::getCodeId, req.getId());
        List<MainDataTourGroupArea> areaList = mainDataTourGroupAreaMapper.selectList(wrapper);
        List<MainDataTourGroupAreaDTO> mainDataTourGroupAreaDTOS = EntityUtil.copyList(areaList, MainDataTourGroupAreaDTO.class);
        mainDataTourGroupQueryDTO.setAreaList(mainDataTourGroupAreaDTOS);
        return mainDataTourGroupQueryDTO;
    }

    /**
     * 查询旅游组别列表
     */
    @Override
    public PageResponse<MainDataTourGroupListDTO> list(MainDataTourGroupListReq req) {
        IPage<MainDataTourGroup> page = new Page<>(req.getPageNo(), req.getPageSize());
        QueryWrapper<MainDataTourGroup> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().like(StringUtils.isNotBlank(req.getTourGroupName()), MainDataTourGroup::getTourGroupName, req.getTourGroupName())
                .eq(null != req.getStatus(), MainDataTourGroup::getStatus, req.getStatus())
                .eq(MainDataTourGroup::getIsDeleted, IsDeletedCode.NO.getCode())
                .orderByDesc(MainDataTourGroup::getGmtModified);
        IPage<MainDataTourGroup> iPage = baseMapper.selectPage(page, queryWrapper);
        List<MainDataTourGroup> mainDataTourGroupList = iPage.getRecords();
        List<MainDataTourGroupListDTO> mainDataTourGroupListDTOS = EntityUtil.copyList(mainDataTourGroupList, MainDataTourGroupListDTO.class);
        if (CollectionUtils.isEmpty(mainDataTourGroupListDTOS)) {
            return new PageResponse<>(new ArrayList<>(), iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
        }
        Set<Long> set = new HashSet<>();
        for (MainDataTourGroupListDTO dto : mainDataTourGroupListDTOS) {
            QueryWrapper<MainDataTourGroupArea> wrapper = new QueryWrapper<>();
            //在这里加上一个目的地名称 如果不是就把腹肌删除
            wrapper.lambda()
                    .eq(MainDataTourGroupArea::getCodeId, dto.getId())
                    .eq(StringUtils.isNotBlank(req.getName()), MainDataTourGroupArea::getAreaName, req.getName());
            List<MainDataTourGroupArea> mdtgal = mainDataTourGroupAreaMapper.selectList(wrapper);
            if (CollectionUtils.isNotEmpty(mdtgal)) {
                List<MainDataTourGroupAreaDTO> mainDataTourGroupAreaDTOS = EntityUtil.copyList(mdtgal, MainDataTourGroupAreaDTO.class);
                dto.setAreaList(mainDataTourGroupAreaDTOS);
            } else {
                if (StringUtils.isNotBlank(req.getName())) {
                    //确定目的地名不为空就标记清除
                    set.add(dto.getId());
                }
            }
        }
        if (set.size() > 0) {
            mainDataTourGroupListDTOS = mainDataTourGroupListDTOS.stream().filter(e -> {
                if (set.contains(e.getId())) {
                    //如果存在删除标记集合里就不要了
                    return false;
                }
                return true;
            }).collect(Collectors.toList());
        }
        return new PageResponse<>(mainDataTourGroupListDTOS, iPage.getCurrent() == 1, iPage.getTotal() <= (iPage.getCurrent() * iPage.getSize()), iPage.getTotal(), iPage.getCurrent(), iPage.getSize());
    }

    @Override
    public MainDataTourGroupDTO listByArea(MainDataTourGroupAreaReq req) {
        QueryWrapper<MainDataTourGroupArea> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MainDataTourGroupArea::getAreaId, req.getAreaId()).or().eq(MainDataTourGroupArea::getAreaName, req.getAreaName());
        MainDataTourGroupArea mainDataTourGroupArea = mainDataTourGroupAreaMapper.selectOne(queryWrapper);
        if (null == mainDataTourGroupArea) {
            return null;
        }
        MainDataTourGroupDTO listDTO = null;
        QueryWrapper<MainDataTourGroup> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(MainDataTourGroup::getId, mainDataTourGroupArea.getCodeId());
        wrapper.lambda().eq(MainDataTourGroup::getIsDeleted, IsDeletedCode.NO.getCode());
        wrapper.lambda().eq(MainDataTourGroup::getStatus, 0);
        MainDataTourGroup mainDataTourGroup = mainDataTourGroupMapper.selectOne(wrapper);
        if (mainDataTourGroup != null) {
            listDTO = EntityUtil.copy(mainDataTourGroup, MainDataTourGroupDTO.class);
            listDTO.setArea(EntityUtil.copy(mainDataTourGroupArea, MainDataTourGroupAreaDTO.class));
        }
        return listDTO;
    }

    @Override
    public MainDataTourGroupCodeQueryDTO queryGroupCode(Long id) {
        QueryWrapper<MainDataTourGroup> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MainDataTourGroup::getId, id);
        queryWrapper.lambda().eq(MainDataTourGroup::getIsDeleted, IsDeletedCode.NO.getCode());
        queryWrapper.lambda().eq(MainDataTourGroup::getStatus, 0);
        MainDataTourGroup mainDataTourGroup = baseMapper.selectOne(queryWrapper);
        QueryWrapper<MainDataTourGroupCode> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(MainDataTourGroupCode::getTourGroupCode, mainDataTourGroup.getTourGroupCode());
        wrapper.lambda().eq(MainDataTourGroupCode::getIsDeleted, IsDeletedCode.NO.getCode());
        wrapper.lambda().eq(MainDataTourGroupCode::getStatus, 0);
        MainDataTourGroupCode mainDataTourGroupCode = mainDataTourGroupCodeMapper.selectOne(wrapper);
        MainDataTourGroupCodeQueryDTO mainDataTourGroupCodeQueryDTO = EntityUtil.copy(mainDataTourGroupCode, MainDataTourGroupCodeQueryDTO.class);
        return mainDataTourGroupCodeQueryDTO;
    }

    /**
     * 旅行团首页目录三级分类
     *
     * @return
     */
    @Override
    public List<CatalogMainDataDTO> getCatalogMainData() {
        return baseMapper.queryCatalogMainData(IsDeletedCode.NO.getCode(), StopStatusCode.NO.getCode());
    }

}
